package com.loongtech.bi.action.flow;

import com.loongtech.bi.action.Base2BiSearchAction;
import com.loongtech.bi.manager.flow.HadoopQueryManager;
import com.loongtech.bi.manager.system.ConfigManager;
import com.loongtech.bi.manager.system.GameParamConfigManager;
import com.loongtech.bi.manager.system.SysLogManager;
import com.loongtech.bi.support.CommonGameParam;
import com.loongtech.bi.support.Session;
import com.loongtech.core.util.Time;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import java.util.*;
import java.util.Map.Entry;

/**
 * 流水查询—货币流水Action
 *
 * @author Marin
 * @date 2015年09月17日
 */
@Controller
@Scope("view")
public class MoneyFlowAction extends Base2BiSearchAction {
	private static final long serialVersionUID = 1L;
    protected Date dateStart = new Date(Time.getBeginningOfDay(Time.currentTime()));
    protected Date dateEnd = new Date(Time.getBeginningOfDay(Time.currentTime()));
    private MoneyFlow queryBean;  // 查询bean
    private Map<String, String> reasonItmes;  // 消耗/获得原因
    private Map<String, String> reasonItmesRevise; // 消耗/获得原因反转
    private Map<String, String> reasonDetailItmes; // 消耗/获得原因细分
    private Map<String, String> reasonDetailItmesRevise; // 消耗/获得原因细分反转
    private Map<String, String> typeItmes = GameParamConfigManager.getItems(CommonGameParam.CURRENCY_TYPE);  // 货币类型
    private Map<String, String> typeItmesRevise = GameParamConfigManager.getItemsRevise(CommonGameParam.CURRENCY_TYPE); // 货币类型反转

    private Map<String, String> rechargeCurrencyItmes = GameParamConfigManager.getItems(CommonGameParam.RECHARGE_CURRENCY_TYPE); // 充值相关类型

    private List<Object[]> result;  // 结果List

    private boolean hasDetailReason;  // 游戏有没有细分原因，如果有，前端显示，如果没有，前端隐藏

    @Autowired
    private ConfigManager configManager;

    @Autowired
    HadoopQueryManager hadoopQueryManager;

    @Autowired
    private SysLogManager sysLogManager;
    @Autowired
    private Session session;

    @PostConstruct
    public void init() {
        queryBean = new MoneyFlow();
        result = new ArrayList<>();

        updateReason();

		/*typeItmes = new LinkedHashMap<>();
        int index = 0;
		for (Entry<String, String> entry : GameParamConfigManager.getItems(CommonGameParam.CURRENCY_TYPE).entrySet()) {
			if (index++ > 0) {
				typeItmes.put(entry.getKey(), entry.getValue());
			}
		}*/

        hasDetailReason = "1".equals(configManager.getConfigValueByName(ConfigManager.HAS_DETAIL_REASON)) ? true : false;
    }

    public void updateReason() {
        reasonItmes = new LinkedHashMap<>();
        reasonDetailItmes = new LinkedHashMap<>();

        if (queryBean.getCurrencytype() == Integer.parseInt(GameParamConfigManager.getItemsRevise(CommonGameParam.MONEY_TYPE).keySet().toArray()[1].toString())) {  // 银两
            reasonItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.MONEY_REASON));
            reasonDetailItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.MONEY_DETAIL_REASON));
        } else if (queryBean.getCurrencytype() == Integer.parseInt(GameParamConfigManager.getItemsRevise(CommonGameParam.RMB_TYPE).keySet().toArray()[1].toString())) {  // 钻石
            reasonItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.RMB_REASON));
            reasonDetailItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.RMB_DETAIL_REASON));
        } else if (queryBean.getCurrencytype() == 99999) {  // 所有与充值相关的类型
            reasonItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.RMB_REASON));
            reasonDetailItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.RMB_DETAIL_REASON));
        } else if (queryBean.getCurrencytype() == -99999) {  // 全部
            Map<String, String> t = new LinkedHashMap<>();
            t.put("全部", GameParamConfigManager.ALL_FLAT);
            reasonItmes.putAll(t);
            reasonDetailItmes.putAll(t);
        } else {
            reasonItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.RMB_REASON));
            reasonDetailItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.RMB_DETAIL_REASON));

            reasonItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.MONEY_REASON));
            reasonDetailItmes.putAll(GameParamConfigManager.getItems(CommonGameParam.MONEY_DETAIL_REASON));
        }
    }

    public void search() {
        sysLogManager.addLog(session.getUserName(), "流水查询—货币流水");

        result = new ArrayList<>();

        FacesContext context = FacesContext.getCurrentInstance();

        // 开始结束时间不能大于当前时间60天
        if (Time.getInterval(new Date(), dateStart) > 60 || Time.getInterval(new Date(), dateEnd) > 60) {
            context.addMessage(null, new FacesMessage("提示", "开始结束时间不能小于当前时间60天!"));
            return;
        }

        // 用户ID，角色ID必要有一个非空
        if (StringUtils.isBlank(queryBean.getUserid()) && StringUtils.isBlank(queryBean.getRoleid())) {
            context.addMessage(null, new FacesMessage("提示", "用户ID，角色ID必须至少有一个非空!"));
            return;
        }

        if (HadoopQueryManager.VISIT_QUEUE.offer("MoneyFlowAction")) {
            System.out.println("VISIT_QUEUE offer MoneyFlowAction ok!");

            StringBuffer sql = new StringBuffer();
            sql.append("select logtime,platform,channel,serverid,userid,roleid,rolelevel,currencytype,reason,param,changenum,leftnum from currency where 1=1 ");
            if (queryBean.getUserid() != null && !"".equals(queryBean.getUserid())) {
                sql.append(" and userid = '");
                sql.append(queryBean.getUserid().trim());
                sql.append("' ");
            }
            if (!StringUtils.isBlank(queryBean.getRoleid())) {
                sql.append(" and cast(roleid as string) = '");
                sql.append(queryBean.getRoleid());
                sql.append("' ");
            }
            if (!"0".equals(queryPlatform)) {
                sql.append(" and platform = ");
                sql.append(queryPlatform);
            }
            if (!"0".equals(queryChannel)) {
                sql.append(" and channel = '");
                sql.append(queryChannel);
                sql.append("' ");
            }
            if (!"0".equals(queryServer)) {
                sql.append(" and serverid = ");
                sql.append(queryServer);
            }
            if (queryBean.getCurrencytype() != -99999) {
                if (queryBean.getCurrencytype() == 99999) {  // 所有充值相关类型
                    ArrayList<String> rcis = new ArrayList<String>(rechargeCurrencyItmes.values());
                    if (rcis != null && rcis.size() > 0) {
                        sql.append(" and (currencytype = ");
                        for (int i = 1; i < rcis.size(); i++) {
                            if (i > 1) {
                                sql.append(" or currencytype = ");
                            }
                            sql.append(rcis.get(i));
                        }

                        sql.append(") ");
                    }
                } else {
                    sql.append(" and currencytype = ");
                    sql.append(queryBean.getCurrencytype());
                }
            }
            if (queryBean.getReason() != -99999) {
                sql.append(" and reason = ");

                // 如果原因小于0，说明原因有重的，这时的处理是：选changenum小于0的
                if (queryBean.getReason() < 0) {
                    sql.append(-queryBean.getReason());
                    sql.append(" and changenum < 0 ");
                } else {
                    sql.append(queryBean.getReason());
                }
            }
            if (queryBean.getParam() != -99999) {
                sql.append(" and param = ");
                sql.append(queryBean.getParam());
            }
            sql.append(" and dt >= '");
            sql.append(Time.getDateStr(dateStart));
            sql.append("' and dt <= '");
            sql.append(Time.getDateStr(dateEnd));
            sql.append("' ");
            sql.append(" order by logtime desc ");

            System.out.println(sql.toString());
            Entry<List<String>, List<Object[]>> ret = hadoopQueryManager.executeSQL(sql.toString());
            if (null == ret || null == ret.getKey() || ret.getKey().isEmpty() || null == ret.getValue()) {
                context.addMessage(null, new FacesMessage("提示", "查询结果为空!"));
                return;
            }

            result = ret.getValue();
        } else {
            System.out.println("VISIT_QUEUE offer MoneyFlowAction failed!");
            context.addMessage(null, new FacesMessage("提示", "当前系统正被访问，为保证服务器稳定，请稍后再试"));
            return;
        }
    }

    // 查询消耗/获得类型
    public String getReasonType(Object reasonType, Object currencyType, Object changenum) {
        String key = reasonType == null ? "" : Math.abs(Integer.parseInt(reasonType.toString())) + "";
        String key1 = currencyType == null ? "" : Math.abs(Integer.parseInt(currencyType.toString())) + "";

        if (Integer.parseInt(key1) == Integer.parseInt(GameParamConfigManager.getItemsRevise(CommonGameParam.MONEY_TYPE).keySet().toArray()[1].toString())) {  // 银两
            reasonItmesRevise = GameParamConfigManager.getItemsRevise(CommonGameParam.MONEY_REASON);
        } else if (Integer.parseInt(key1) == Integer.parseInt(GameParamConfigManager.getItemsRevise(CommonGameParam.RMB_TYPE).keySet().toArray()[1].toString())) {  // 钻石
            reasonItmesRevise = GameParamConfigManager.getItemsRevise(CommonGameParam.RMB_REASON);
        }

        if (reasonItmesRevise == null) {  // 可选列表为空，直接返回
            return key;
        } else {
            int num = Integer.parseInt(changenum.toString());  // 改变值
            String positiveGet = reasonItmesRevise.get(key);  // reasonItmesRevise中查询正key，没空表示没配key
            String negativeGet = reasonItmesRevise.get("-" + key);  // reasonItmesRevise中查询负key，没空表示没配-key

            if (num < 0 && negativeGet != null) {  // 改变值小于0且配了-key才返回negativeGet
                return negativeGet;
            } else {
                return positiveGet == null ? key : positiveGet;
            }
        }
    }

    // 查询消耗/获得细分类型
    public String getReasonDetailType(Object reasonDeailType, Object currencyType) {
        String key = reasonDeailType == null ? "" : Math.abs(Integer.parseInt(reasonDeailType.toString())) + "";
        String key1 = currencyType == null ? "" : Math.abs(Integer.parseInt(currencyType.toString())) + "";

        if (Integer.parseInt(key1) == GameParamConfigManager.getParamType(CommonGameParam.MONEY_TYPE)) {  // 银两
            reasonDetailItmesRevise = GameParamConfigManager.getItemsRevise(CommonGameParam.MONEY_DETAIL_REASON);
        } else if (Integer.parseInt(key1) == GameParamConfigManager.getParamType(CommonGameParam.RMB_TYPE)) {  // 钻石
            reasonDetailItmesRevise = GameParamConfigManager.getItemsRevise(CommonGameParam.RMB_DETAIL_REASON);
        }

        return (reasonDetailItmesRevise == null || reasonDetailItmesRevise.get(key) == null) ? key : reasonDetailItmesRevise.get(key);
    }

    // 元宝类型
    public String getMoneyType(Object currencyType) {
        String key = currencyType == null ? "" : Math.abs(Integer.parseInt(currencyType.toString())) + "";
        return (typeItmesRevise.get(key) == null) ? key : typeItmesRevise.get(key);
    }

    public class MoneyFlow {
        private String logtime; // 时间
        private String hostname; // 服务器主机名
        private String modulename; // 模块名
        private int gameid; // 游戏ID
        private int serverid; // 服务器ID
        private long logid; // 日志编号
        private String logtype; // 日志类型
        private int platform; // 平台ID
        private String channel; // 渠道标识
        private String mac; // 设备mac地址
        private String userid; // 账号ID
        private String roleid; // 角色ID
        private int rolelevel; // 角色等级
        private int currencytype = -99999; // 货币类型
        private int reason = -99999; // 消耗或获得的原因
        private int changenum; // 消耗或获得数量
        private long leftnum; // 当前此类型货币总量
        private long param = -99999; // reason的细分类型
        private String dt; // 时间

        public String getLogtime() {
            return logtime;
        }

        public void setLogtime(String logtime) {
            this.logtime = logtime;
        }

        public String getHostname() {
            return hostname;
        }

        public void setHostname(String hostname) {
            this.hostname = hostname;
        }

        public String getModulename() {
            return modulename;
        }

        public void setModulename(String modulename) {
            this.modulename = modulename;
        }

        public int getGameid() {
            return gameid;
        }

        public void setGameid(int gameid) {
            this.gameid = gameid;
        }

        public int getServerid() {
            return serverid;
        }

        public void setServerid(int serverid) {
            this.serverid = serverid;
        }

        public long getLogid() {
            return logid;
        }

        public void setLogid(long logid) {
            this.logid = logid;
        }

        public String getLogtype() {
            return logtype;
        }

        public void setLogtype(String logtype) {
            this.logtype = logtype;
        }

        public int getPlatform() {
            return platform;
        }

        public void setPlatform(int platform) {
            this.platform = platform;
        }

        public String getChannel() {
            return channel;
        }

        public void setChannel(String channel) {
            this.channel = channel;
        }

        public String getMac() {
            return mac;
        }

        public void setMac(String mac) {
            this.mac = mac;
        }

        public String getUserid() {
            return userid;
        }

        public void setUserid(String userid) {
            this.userid = userid;
        }

        public String getRoleid() {
            return roleid;
        }

        public void setRoleid(String roleid) {
            this.roleid = roleid;
        }

        public int getRolelevel() {
            return rolelevel;
        }

        public void setRolelevel(int rolelevel) {
            this.rolelevel = rolelevel;
        }

        public int getCurrencytype() {
            return currencytype;
        }

        public void setCurrencytype(int currencytype) {
            this.currencytype = currencytype;
        }

        public int getReason() {
            return reason;
        }

        public void setReason(int reason) {
            this.reason = reason;
        }

        public int getChangenum() {
            return changenum;
        }

        public void setChangenum(int changenum) {
            this.changenum = changenum;
        }

        public long getLeftnum() {
            return leftnum;
        }

        public void setLeftnum(long leftnum) {
            this.leftnum = leftnum;
        }

        public String getDt() {
            return dt;
        }

        public void setDt(String dt) {
            this.dt = dt;
        }

        public long getParam() {
            return param;
        }

        public void setParam(long param) {
            this.param = param;
        }
    }

    @Override
    protected String csvContent() {
        return null;
    }

    @Override
    protected String csvFileName() {
        return null;
    }

    public MoneyFlow getQueryBean() {
        return queryBean;
    }

    public void setQueryBean(MoneyFlow queryBean) {
        this.queryBean = queryBean;
    }

    public List<Object[]> getResult() {
        return result;
    }

    public void setResult(List<Object[]> result) {
        this.result = result;
    }

    public Date getDateStart() {
        return dateStart;
    }

    public void setDateStart(Date dateStart) {
        this.dateStart = dateStart;
    }

    public Map<String, String> getReasonItmes() {
        return reasonItmes;
    }

    public void setReasonItmes(Map<String, String> reasonItmes) {
        this.reasonItmes = reasonItmes;
    }

    public Map<String, String> getReasonItmesRevise() {
        return reasonItmesRevise;
    }

    public void setReasonItmesRevise(Map<String, String> reasonItmesRevise) {
        this.reasonItmesRevise = reasonItmesRevise;
    }

    public Map<String, String> getReasonDetailItmes() {
        return reasonDetailItmes;
    }

    public void setReasonDetailItmes(Map<String, String> reasonDetailItmes) {
        this.reasonDetailItmes = reasonDetailItmes;
    }

    public boolean isHasDetailReason() {
        return hasDetailReason;
    }

    public void setHasDetailReason(boolean hasDetailReason) {
        this.hasDetailReason = hasDetailReason;
    }

    public Map<String, String> getTypeItmes() {
        return typeItmes;
    }

    public void setTypeItmes(Map<String, String> typeItmes) {
        this.typeItmes = typeItmes;
    }

    public Map<String, String> getTypeItmesRevise() {
        return typeItmesRevise;
    }

    public void setTypeItmesRevise(Map<String, String> typeItmesRevise) {
        this.typeItmesRevise = typeItmesRevise;
    }

    public Map<String, String> getRechargeCurrencyItmes() {
        return rechargeCurrencyItmes;
    }

    public void setRechargeCurrencyItmes(Map<String, String> rechargeCurrencyItmes) {
        this.rechargeCurrencyItmes = rechargeCurrencyItmes;
    }

    @Override
    public Date getDateEnd() {
        return dateEnd;
    }

    @Override
    public void setDateEnd(Date dateEnd) {
        this.dateEnd = dateEnd;
    }
}
